package com.boot.core.interceptor

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.boot.config.RequestWrapper
import com.boot.core.define.SESSION_KEY
import com.boot.core.result.ResultEnum
import com.boot.core.result.ResultTo
import com.boot.core.util.AjaxUtil
import com.boot.core.util.ManagerKit
import com.boot.mgt.dao.mysql.TaPoliceMapper
import com.boot.mgt.dao.mysql.TaSessionMapper
import com.boot.mgt.model.TaPolice
import com.boot.mgt.model.TaSession
import com.boot.mgt.service.TaPoliceService
import org.apache.commons.lang3.StringUtils
import org.hsqldb.lib.StringUtil
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.lang.Nullable
import org.springframework.web.servlet.HandlerInterceptor
import org.springframework.web.servlet.ModelAndView
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse


/**
 * @author rankai
 * createTime 2018-03-2018/3/11 14:25
 */
class AuthInterceptor : HandlerInterceptor {

    @Autowired
    private lateinit var sessionMapper: TaSessionMapper

    @Autowired
    private lateinit var policeMapper: TaPoliceMapper

    @Autowired
    private lateinit var taPoliceService: TaPoliceService

    @Throws(Exception::class)
    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        val map = request.parameterMap?.apply {
            if (containsKey("paper_image_base64")) {
                remove("paper_image_base64")
            }
            if (containsKey("image_base64")) {
                remove("image_base64")
            }
        }
        log.info("\n>>> Request URI:${request.requestURI}\n>>> from：${request.remoteAddr}\n>>> Request params:${JSON.toJSONString(map)}")

        val sessionKey = request.getParameter(SESSION_KEY)
//        val sessionKey = "1bdca3c4-c017-4bf5-b1b3-ce29ec9a6327"
        if (sessionKey.isNullOrBlank()) {
            log.info("get Request URI:${request.requestURI} session_key is Null, try post")
            //var body = getPostBody(request) as String?
            val requestWrapper = RequestWrapper(request)
            val body: String = requestWrapper.body
            if(StringUtils.isNotEmpty(body)) {
                return true
                /*var session_key = JSONObject.parseObject(body)["session_key"] as String?
                if (ACCIDENT_SESSION_KEY_ARRAY.contains(session_key)) {
                    log.info("post Request URI:${request.requestURI} form Outside")
                    request.setAttribute(ManagerKit.OUTSIDE, 1)
                    log.debug("post Request URI:${request.requestURI}:session_key[$sessionKey]Validate Success")
                    request.setAttribute("regionAdd", "12212112")
                    return true
                } else {
                    log.info("post Request URI:${request.requestURI} session_key[$sessionKey] not exist 2")
                    //                    AjaxUtil.outputMessage(response, ResultTo(ResultEnum.NO_LOGIN))
                    return true
                }*/
            } else {
                AjaxUtil.outputMessage(response, ResultTo(ResultEnum.NO_LOGIN))
            }
//            return true
        } else {
            if (ACCIDENT_SESSION_KEY_ARRAY.contains(sessionKey)) {
                log.info(" Request URI:${request.requestURI} form Outside")
                request.setAttribute(ManagerKit.OUTSIDE, 1)
                log.debug(" Request URI:${request.requestURI}:session_key[$sessionKey] Validate Success")
                if (map != null) {
                    if(map.contains("policeNumber")) {
                        val sessionOutside = TaSession()
                        sessionOutside.sessionKey = sessionKey
                        sessionMapper.insertSelective(sessionOutside)
                        val policeOutside = TaPolice()
                        policeOutside.policeNumber = map.get("policeNumber")?.get(0).toString()
                        /*
                        val policeOneOutside = policeMapper.selectOne(policeOutside)
                        request.setAttribute(ManagerKit.POLICE_ID, policeOneOutside.id)
                        request.setAttribute(ManagerKit.POLICE_LEVEL, policeOneOutside.level)
                        request.setAttribute(ManagerKit.POLICE_NUMBER, policeOneOutside.policeNumber)
                        request.setAttribute(ManagerKit.ORG_NUM, policeOneOutside.xqdw)
                        */

                        var policeOne  = taPoliceService.searchPoliceById(policeOutside.policeNumber)
                        request.setAttribute(ManagerKit.POLICE_ID, policeOne["user_id"])
                        request.setAttribute(ManagerKit.POLICE_LEVEL, 2)
                        request.setAttribute(ManagerKit.POLICE_NUMBER, policeOne["user_name"] as String)
                        request.setAttribute(ManagerKit.ORG_NUM, policeOne["region_id"])
                    }
                }
                return true
            }
            val session = TaSession()
            session.sessionKey = sessionKey
            val sessionOne = sessionMapper.selectOne(session)
            if (sessionOne != null) {
                log.debug(" Request URI:${request.requestURI}session_key[$sessionKey] Validate Success, and match of police ID is:${sessionOne.policeNumber}")
                /*
                val police = TaPolice()
                police.policeNumber = sessionOne.policeNumber
                val policeOne = policeMapper.selectOne(police)
                request.setAttribute(ManagerKit.POLICE_ID, policeOne.id)
                request.setAttribute(ManagerKit.POLICE_LEVEL, policeOne.level)
                request.setAttribute(ManagerKit.POLICE_NUMBER, policeOne.policeNumber)
                request.setAttribute(ManagerKit.ORG_NUM, policeOne.xqdw)
                */

                var policeOne  = taPoliceService.searchPoliceById(sessionOne.policeNumber)
                request.setAttribute(ManagerKit.POLICE_ID, policeOne["user_id"])
                request.setAttribute(ManagerKit.POLICE_LEVEL, 2)
                request.setAttribute(ManagerKit.POLICE_NUMBER, policeOne["user_name"] as String)
                request.setAttribute(ManagerKit.ORG_NUM, policeOne["region_id"])
                return true
            } else {
                log.info(" Request URI:${request.requestURI} session_key[$sessionKey] not exist 3")
//                AjaxUtil.outputMessage(response, ResultTo(ResultEnum.NO_LOGIN))
            }
        }
        return false
    }

    @Throws(Exception::class)
    override fun postHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any, @Nullable modelAndView: ModelAndView?) {
        println("post handle finish");
    }

    @Throws(Exception::class)
    override fun afterCompletion(request: HttpServletRequest, response: HttpServletResponse, handler: Any, @Nullable ex: java.lang.Exception?) {

    }

    fun requestJson2Map(request: HttpServletRequest): Map<*, *>? {
        try {
            val streamReader = BufferedReader(InputStreamReader(request.inputStream, "UTF-8"))
            val responseStrBuilder = StringBuilder()
            var inputStr: String
            while (true) {
                inputStr = streamReader.readLine()
                if (inputStr != null) {
                    responseStrBuilder.append(inputStr)
                    continue
                }
                break
            }
            return JSON.parseObject(responseStrBuilder.toString(), Map::class.java)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    companion object {
        private val log: Logger = LoggerFactory.getLogger(this::class.java)

        private val ACCIDENT_SESSION_KEY_ARRAY: Array<String> = arrayOf(
                "1bdca3c4-c017-4bf5-b1b3-ce29ec9a6327")
    }

    private fun getPostBody(request: HttpServletRequest): String {
        var body = ""
        val stringBuilder = java.lang.StringBuilder()
        var bufferedReader: BufferedReader? = null
        var inputStream: InputStream? = null
        try {
            inputStream = request.getInputStream()
            if (inputStream != null) {
                bufferedReader = BufferedReader(InputStreamReader(inputStream))
                val charBuffer = CharArray(128)
                var bytesRead = -1
                while (bufferedReader.read(charBuffer).also { bytesRead = it } > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead)
                }
            } else {
                stringBuilder.append("")
            }
        } catch (ex: IOException) {
            ex.printStackTrace()
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
        body = stringBuilder.toString()
        return body
    }

}
